package com.whsxt.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.whsxt.common.CodeMsg;
import com.whsxt.domain.Role;
import com.whsxt.dto.RoleDto;
import com.whsxt.exception.BusinessException;
import com.whsxt.mapper.RoleMapper;
import com.whsxt.service.RoleService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.List;
import java.util.Set;

import static cn.hutool.extra.validation.ValidationUtil.validate;

@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleMapper roleMapper;

    /**
     * 分页查询角色的数据
     * @param roleDto 查询条件
     * @return 封装角色分页数据的信息
     */
    @Override
    public PageInfo<Role> findPage(RoleDto roleDto) {
        // 开启分页
        Page<Object> objects = PageHelper.startPage(roleDto.getPage(), roleDto.getLimit());
        // 全查询数据
        List<Role> roles = roleMapper.selectPage(roleDto);

        PageInfo<Role> rolePageInfo = new PageInfo<>(roles);

        rolePageInfo.setTotal(objects.getTotal());

        return rolePageInfo;
    }

    /**
     * 新增角色
     *
     * @param roleDto
     * @return
     */
    @Override
    public boolean save(RoleDto roleDto) {
        // 校验角色数据
        validate(roleDto);
        // 属性的复制
        Role role = new Role();
        BeanUtils.copyProperties(roleDto, role);
        // 填充默认值（无）
        // 新增数据
        int count = roleMapper.insert(role);
        return count > 0;
    }


    /**
     * 批量删除角色
     *
     * @param ids
     * @return
     */
    @Override
    public boolean batchRemove(List<Integer> ids) {
        return roleMapper.batchRemove(ids) > 0;
    }

    /**
     * 修改角色数据
     *
     * @param roleDto
     * @return
     */
    @Override
    public boolean update(RoleDto roleDto) {
        // 先查询数据库是否存在该数据，
        Role role = roleMapper.selectByPrimaryKey(roleDto.getId());
        if(role == null){
            throw new IllegalArgumentException("角色不存在");
        }
        if(!role.getTag().equals(roleDto.getTag())){
            throw new IllegalArgumentException("角色标识数据不一致");
        }

        Role update = new Role();
        // 属性的复制
        BeanUtils.copyProperties(roleDto, update);

        // 修改数据
        return roleMapper.updateByPrimaryKeySelective(update) > 0;
    }

    /**
     * 加载所有的角色数据
     *
     * @return
     */
    @Override
    public List<Role> loadRoles() {
        RoleDto query = new RoleDto();
        return roleMapper.selectPage(query);
    }

    /**
     * 通过用户id 查询出所拥有的角色id
     * @param userId
     * @return
     */
    @Override
    public List<Integer> selectRoleIdsByUserId(Integer userId) {
        List<Integer> roleIds = roleMapper.selectRoleIdsByUserId(userId);
        return roleIds == null? Collections.emptyList() : roleIds;
    }

    /**
     * 通过拥护ID查询所有的角色
     * @param userId
     * @return
     */
    @Override
    public List<Role> selectRolesByUserId(Integer userId) {

        return roleMapper.selectByUserId(userId);
    }

    /**
     * 为角色赋予权限
     *
     * @param roleId
     * @param permIds
     * @return
     */
    @Override
    @Transactional
    public boolean assign(Integer roleId, Integer[] permIds) {
        // 删除角色权限关系
        int deleteRows = roleMapper.deletePermsByRoleId(roleId);

        // 新增权限关系
        int insertRows = 0;
        if(permIds != null && permIds.length > 0){
            insertRows = roleMapper.assign(roleId, permIds);
        }
        return insertRows + deleteRows > 0;
    }

    /**
     * 数据的校验
     * @param roleDto
     */
    private void validate(RoleDto roleDto) {

        if(!StringUtils.hasText(roleDto.getName())){
            throw new IllegalArgumentException("角色名称不能为空");
        }

        if(!StringUtils.hasText(roleDto.getTag())){
            throw new IllegalArgumentException("角色的标识不能为空");
        }

        int count = roleMapper.selectCountByTag(roleDto.getTag());

        if(count > 0){
            throw new BusinessException(CodeMsg.ROLE_TAG_FOUND, roleDto.getTag());
        }
    }

}
